package cn.liccshop.core.service.shopGoods.service;

import cn.liccshop.core.entity.*;
import cn.liccshop.core.service.shopAttribute.mapper.ShopAttributeMapper;
import cn.liccshop.core.service.shopBrowseRecord.mapper.ShopBrowseRecordMapper;
import cn.liccshop.core.service.shopCategory.mapper.ShopCategoryMapper;
import cn.liccshop.core.service.shopGoods.mapper.ShopGoodsMapper;
import cn.liccshop.core.service.shopGoods.service.IShopGoodsService;
import cn.liccshop.core.service.shopGoodsAttr.mapper.ShopGoodsAttrMapper;
import cn.liccshop.core.service.shopPhoto.mapper.ShopPhotoMapper;
import cn.liccshop.core.service.shopProducts.mapper.ShopProductsMapper;
import cn.liccshop.core.utils.ObjectToOtherUtils;
import cn.liccshop.sys.cache.CommonCacheUtil;
import cn.liccshop.sys.constants.Constants;
import cn.liccshop.sys.exception.MySystemException;
import cn.liccshop.sys.utils.MapToObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 商品表 服务实现类
 * </p>
 *
 * @author LiCC
 * @since 2019-04-08
 */
@Service
public class ShopGoodsServiceImpl extends ServiceImpl<ShopGoodsMapper, ShopGoods> implements IShopGoodsService {

    @Autowired
    private ShopPhotoMapper shopPhotoMapper;
    @Autowired
    private ShopGoodsAttrMapper goodsAttrMapper;
    @Autowired
    private ShopAttributeMapper attributeMapper;
    @Autowired
    private ShopProductsMapper productsMapper;
    @Autowired
    private ShopCategoryMapper categoryMapper;
    @Autowired
    private ShopGoodsMapper goodsMapper;
    @Autowired
    private ShopBrowseRecordMapper browseRecordMapper;
    @Autowired
    private CommonCacheUtil commonCacheUtil;

    /** 新品推荐 **/
    private static final Byte isNewGoods = 1;
    /** 热销商品推荐 **/
    private static final Byte isHotGoods = 1;

    @Transactional(rollbackFor=Exception.class)
    @Override
    public ShopGoods addShopGoods(Map<String, Object> params, String userId) throws MySystemException {
        ShopGoods shopGoods = new ShopGoods();
        shopGoods.setCatId(ObjectToOtherUtils.toString(params.get("catId")))
                .setGoodsSn(ObjectToOtherUtils.toString(params.get("goodsSn")))
                .setGoodsName(ObjectToOtherUtils.toString(params.get("goodsName")))
                .setGoodsUnit(ObjectToOtherUtils.toString(params.get("goodsUnit")))
                .setKeywords(ObjectToOtherUtils.toString(params.get("keywords")))
                .setGoodsWeight(ObjectToOtherUtils.toBigDecimal(params.get("goodsWeight")))
                .setShopPrice(ObjectToOtherUtils.toBigDecimal(params.get("shopPrice")))
                .setCostPrice(ObjectToOtherUtils.toBigDecimal(params.get("costPrice")))
                .setMarketPrice(ObjectToOtherUtils.toBigDecimal(params.get("marketPrice")))
                .setGoodsBrief(ObjectToOtherUtils.toString(params.get("goodsBrief")))
                .setGoodsDesc(ObjectToOtherUtils.toString(params.get("goodsDesc")))
                .setSellerNote(ObjectToOtherUtils.toString(params.get("sellerNote")))
                .setReviewStatus(Constants.GOODS_STATUS_15)
                .setCreateBy(userId);
        baseMapper.insert(shopGoods);
        /** 保存图片信息 开始 **/
        List<Map<String, Object>> imgInfos = (List<Map<String, Object>>) params.get("imgInfos");
        List<ShopPhoto> photos = new ArrayList<>();
        for (Map<String, Object> imgInfo : imgInfos) {
            /** 遍历保存图片信息**/
            photos.add(new ShopPhoto()
                    .setId(UUID.randomUUID().toString().replaceAll("-", ""))
                    .setGoodsId(shopGoods.getId())
                    .setUrl(ObjectToOtherUtils.toString(imgInfo.get("url")))
                    .setType(ObjectToOtherUtils.toInteger(imgInfo.get("type")))
                    .setPhotoSort(ObjectToOtherUtils.toInteger(imgInfo.get("photoSort")))
                    .setCreateBy(userId));

        }
        /** 保存图片信息 **/
        shopPhotoMapper.insertShopPhotoBatch(photos);
        /** 保存图片信息 结束 **/

        /** 分类属性值 开始 **/
        /** 获取属性信息 **/
        JSONArray goodsAttrs = (JSONArray) params.get("attrInfos");
        List<ShopGoodsAttr> shopGoodsAttrs = new ArrayList<>();
        for (Object goodsAttrInfos : goodsAttrs){
            /** 遍历分类属性 **/
            Map<String, Object> goodsAttrInfosMap = (Map<String, Object>) goodsAttrInfos;
            /** 获取该分类属性下的属性列 **/
            JSONArray goodsAttrInfoArray = (JSONArray) goodsAttrInfosMap.get("goodsAttrs");
            for (Object goodsAttr : goodsAttrInfoArray){
                /** 遍历属性列，获取分类属性的某一类属性的一个值 **/
                Map<String, Object> goodsAttrMap = (Map<String, Object>) goodsAttr;
                ShopGoodsAttr shopGoodsAttr = new ShopGoodsAttr()
                        .setGoodsId(shopGoods.getId())
                        .setAttrId(ObjectToOtherUtils.toString(goodsAttrMap.get("attrId")))
                        .setAttrValue(ObjectToOtherUtils.toString(goodsAttrMap.get("attrValue")))
                        .setAttrSort(ObjectToOtherUtils.toInteger(goodsAttrMap.get("keyId")));
                /** 插入分类属性信息 **/
                goodsAttrMapper.insert(shopGoodsAttr);
            }
            /** 分类的某一属性的所有属性值遍历完成 **/
        }
        /** 分类的所有属性遍历完成 **/
        /** 分类属性值 结束 **/
        /** 商品添加结束 **/
        return shopGoods;
    }

    @Override
    @Transactional(rollbackFor=Exception.class)
    public ShopGoods updateGoodsAllInfo(Map<String, Object> params) throws MySystemException {
        /** 拿到商品信息基本数据 **/
        ShopGoods goods = MapToObjectUtil.mapToEntity((Map<String, Object>) params.get("goodInfo"), ShopGoods.class);
        /** 拿到商品图片信息数据 **/
        List<ShopPhoto> photos = MapToObjectUtil.mapToList((JSONArray) params.get("imgInfos"), ShopPhoto.class);
        for (ShopPhoto photo : photos){
            photo.setId(UUID.randomUUID().toString().replaceAll("-", "")).setGoodsId(goods.getId());
        }
        baseMapper.updateById(goods);
        shopPhotoMapper.delete(new QueryWrapper<>(new ShopPhoto().setGoodsId(goods.getId())));
        shopPhotoMapper.insertShopPhotoBatch(photos);
        goodsAttrMapper.delete(new QueryWrapper<>(new ShopGoodsAttr().setGoodsId(goods.getId())));
        /** 分类属性值 开始 **/
        /** 获取属性信息 **/
        JSONArray goodsAttrs = (JSONArray) params.get("attrInfos");
        for (Object goodsAttrInfos : goodsAttrs){
            /** 遍历分类属性 **/
            Map<String, Object> goodsAttrInfosMap = (Map<String, Object>) goodsAttrInfos;
            /** 获取该分类属性下的属性列 **/
            JSONArray goodsAttrInfoArray = (JSONArray) goodsAttrInfosMap.get("goodsAttrs");
            for (Object goodsAttr : goodsAttrInfoArray){
                /** 遍历属性列，获取分类属性的某一类属性的一个值 **/
                Map<String, Object> goodsAttrMap = (Map<String, Object>) goodsAttr;
                ShopGoodsAttr shopGoodsAttr = new ShopGoodsAttr()
                        .setGoodsId(goods.getId())
                        .setAttrId(ObjectToOtherUtils.toString(goodsAttrMap.get("attrId")))
                        .setAttrValue(ObjectToOtherUtils.toString(goodsAttrMap.get("attrValue")))
                        .setAttrSort(ObjectToOtherUtils.toInteger(goodsAttrMap.get("attrSort")));
                /** 插入分类属性信息 **/
                goodsAttrMapper.insert(shopGoodsAttr);
            }
            /** 分类的某一属性的所有属性值遍历完成 **/
        }
        /** 分类的所有属性遍历完成 **/
        /** 分类属性值 结束 **/
        return goods;
    }

    @Transactional(rollbackFor=Exception.class)
    @Override
    public boolean deleteGoodsById(String id) throws MySystemException {
        /** 删除商品基本信息成功 **/
        int isSuccess = baseMapper.deleteById(id);
        /** 删除商品图片信息成功 **/
        isSuccess = shopPhotoMapper.delete(new QueryWrapper<>(new ShopPhoto().setGoodsId(id)));
        /** 删除商品属性信息成功 **/
        isSuccess = goodsAttrMapper.delete(new QueryWrapper<>(new ShopGoodsAttr().setGoodsId(id)));
        return false;
    }

    @Override
    public Map<String, Object> getGoodsOfHome() {
        Map<String, Object> data = new HashMap<>();
        List<ShopGoods> newGoodsDB = baseMapper.selectList(new QueryWrapper<>(new ShopGoods().setReviewStatus(Constants.GOODS_STATUS_10).setNewGoods(isNewGoods)).orderByDesc("create_date"));
        if (CollectionUtils.isEmpty(newGoodsDB)){
            /** 新品推荐没有，自动获取最新添加的商品 **/
            newGoodsDB = baseMapper.selectList(new QueryWrapper<>(new ShopGoods().setReviewStatus(Constants.GOODS_STATUS_10)).orderByDesc("create_date").last("limit 0,20"));
        }
        List<ShopGoods> hotGoodsDB = (List<ShopGoods>) this.getHotGoodsInfo(1,100,new ShopGoods().setHot((byte) 1)).get("records");
        if (CollectionUtils.isEmpty(hotGoodsDB)){
            hotGoodsDB = (List<ShopGoods>) this.getHotGoodsInfo(1,20,new ShopGoods()).get("records");
        }
        data.put("newGoods", getGoodsOfHomeUtil(newGoodsDB));
        data.put("hotGoods", getGoodsOfHomeUtil(hotGoodsDB));
        return data;
    }

    @Override
    public Map<String, Object> getGoodsInfoByIdPro(String goodsId, String catId, String userId) {
        Map<String, Object> data = new HashMap<>();
        /** 获取商品信息 **/
        ShopGoods shopGoods = baseMapper.selectById(goodsId);
        data.put("shopGoods", shopGoods);
        /** 获取轮播图信息 **/
        List<ShopPhoto> imgUidList = shopPhotoMapper.selectList(new QueryWrapper<>(new ShopPhoto().setGoodsId(goodsId).setType(2)).orderByAsc("photo_sort"));
        data.put("imgUidList", imgUidList);
        /** 获取详情图信息 **/
        List<ShopPhoto> imgUidThumb = shopPhotoMapper.selectList(new QueryWrapper<>(new ShopPhoto().setGoodsId(goodsId).setType(1)).orderByAsc("photo_sort"));
        data.put("imgUidThumb", imgUidThumb);
        /** 获取商品分类属性 **/
        List<ShopAttribute> shopAttributes = attributeMapper.selectList(new QueryWrapper<>(new ShopAttribute().setCatId(shopGoods.getCatId())).orderByAsc("sort_order"));
        data.put("shopAttributes", shopAttributes);
        /** 获取属性对应的值 **/
        List<Object> goodsAttrsList = new ArrayList<>();
        for (ShopAttribute shopAttribute : shopAttributes){
            /** 获取属性的属性值 **/
            Map<String, Object> goodsAttrsMap = new HashMap<>();
            List<ShopGoodsAttr> goodsAttrs = goodsAttrMapper.selectList(new QueryWrapper<>(new ShopGoodsAttr().setGoodsId(goodsId).setAttrId(shopAttribute.getAttrId())).orderByAsc("attr_sort"));
            /** 保存该属性属性值 **/
            goodsAttrs.get(0).setShowImgFlag((byte) 1);
            goodsAttrsMap.put("data",goodsAttrs);
            goodsAttrsMap.put("name",shopAttribute.getAttrName());
//            goodsAttrsMap.put("initAttrTag",true);
            goodsAttrsList.add(goodsAttrsMap);
        }
        data.put("goodsAttrs", goodsAttrsList);
        /** 获取商品属性值组合的信息 **/
        List<ShopProducts> products = productsMapper.selectList(new QueryWrapper<>(new ShopProducts().setGoodsId(goodsId)).orderByAsc("product_sort"));
        data.put("products", products);
        /** 插入浏览信息 **/
        if (StringUtils.isNotBlank(userId)){
            /** 用户已经登录 **/
            List<ShopBrowseRecord> browseRecords = browseRecordMapper.selectList(new QueryWrapper<>(new ShopBrowseRecord().setUserId(userId)).orderByDesc("create_date").last("limit 0, 1"));
            if (CollectionUtils.isEmpty(browseRecords)||!browseRecords.get(0).getGoodId().equals(goodsId)){
                /** 如果浏览记录为空，或者 第一条浏览记录不是该商品 插入浏览记录 **/
                browseRecordMapper.insert(new ShopBrowseRecord()
                        .setUserId(userId)
                        .setGoodId(goodsId)
                        .setUrl(imgUidList.get(0).getUrl())
                        .setPrice(shopGoods.getShopPrice())
                        .setGoodsName(shopGoods.getGoodsName()));
            }
        }
        return data;
    }

    @Override
    public Map<String, Object> getGoodsInfosByCatIdPro(String catId, Integer pagesize, Integer currentPage) {
        /** 获取父级分类信息--开始 **/
        Map<String, Object> data = new HashMap<>();
        /** 获取本分类信息 **/
        ShopCategory categoryFist = null;
        ShopCategory categorySecond = null;
        ShopCategory categoryThird = null;
        categoryFist = categoryMapper.selectById(catId);
        if (categoryFist != null && StringUtils.isNotBlank(categoryFist.getParentId())){
            /** 本分类存在父级分类 **/
            categorySecond = categoryMapper.selectById(categoryFist.getParentId());
        }
        if (categorySecond != null && StringUtils.isNotBlank(categorySecond.getParentId())){
            /** 父级分类也存在父级分类 **/
            categoryThird = categoryMapper.selectById(categorySecond.getParentId());
        }
        /** 获取父级分类信息--结束 **/
        /** 获取分类商品信息 **/
        IPage<ShopGoods> IPage = getGoodsInfosIncludeChildrenByCatId(catId, pagesize, currentPage);
        /** 装配分类信息--开始 **/
        List<ShopCategory> categories = new ArrayList<>();
        if (categoryThird != null && StringUtils.isNotBlank(categoryThird.getId())){
            categories.add(categoryThird);
        }
        if (categorySecond != null && StringUtils.isNotBlank(categorySecond.getId())){
            categories.add(categorySecond);
        }
        if (categoryFist != null && StringUtils.isNotBlank(categoryFist.getId())){
            categories.add(categoryFist);
        }
        /** 装配分类信息--结束 **/
        /** 封装分类信息 **/
        data.put("categories", categories);
        /** 封装商品信息 **/
        data.put("goods", getGoodsOfHomeUtil(IPage.getRecords()));
        IPage.setRecords(null);
        data.put("iPage", IPage);
        return data;
    }

    @Override
    public Map<String, Object> filterGoodsByNamePro(String filterName, int page, int size) {
        /** 分页获取符合条件的在售商品 **/
        Wrapper<ShopGoods> wrapper = new QueryWrapper<>(new ShopGoods().setReviewStatus(Constants.GOODS_STATUS_10))
                .like("goods_sn", filterName)
                .or()
                .like("goods_name", filterName)
                .or()
                .like("keywords", filterName)
                .or()
                .like("goods_brief", filterName)
                .or()
                .like("goods_desc", filterName)
                .orderByAsc("create_date");
        IPage<ShopGoods> iPage = new Page<>(page, size);
        baseMapper.selectPage(iPage, wrapper);
        /** 获取分类商品信息--结束 **/
        Map<String, Object> data = new HashMap<>();
        /** 封装商品信息 **/
        data.put("goods", getGoodsOfHomeUtil(iPage.getRecords()));
        iPage.setRecords(null);
        data.put("iPage", iPage);
        return data;
    }

    @Override
    public Map<String, Object> getHotGoodsInfo(int page, int size, ShopGoods shopGoods) {
        /** 存储数据 **/
        Map<String, Object> data = new HashMap<>();
        data.put("size", size);
        data.put("current", page);
        /** 获取热销推荐商品ID 以及销量 **/
        List<Map.Entry<String,Integer>> list = commonCacheUtil.getCacheForGoodsOfHot();
        /** 存储商品信息 **/
        List<ShopGoods> records = new ArrayList<>();
        /** 如果推荐为空 则是选择推荐商品列表 **/
        if(shopGoods==null||shopGoods.getHot()==null){
            if (CollectionUtils.isNotEmpty(list)){
                data.put("total", list.size());
                data.put("searchCount", true);
                int num = page * size;
                for (int i = size*(page-1), k = size*(page-1); k < num; i++, k++){
                    if (i<list.size()){
                        /** 获取商品信息 **/
                        ShopGoods shopGoodsData = baseMapper.selectById(list.get(i).getKey());
                        if (shopGoodsData!=null&&shopGoodsData.getReviewStatus().intValue()==Constants.GOODS_STATUS_10) {
                            shopGoodsData.setHotSalesVolume(list.get(i).getValue());
                            records.add(shopGoodsData);
                        } else {
                            k--;
                        }
                    } else {
                        break;
                    }
                }
            }
            /** 保存商品信息 **/
            data.put("records", records);
        } else {
            /** 获取热销商品 **/
            List<ShopGoods> shopGoodsList = baseMapper.selectList(new QueryWrapper<>(new ShopGoods().setReviewStatus(Constants.GOODS_STATUS_10).setHot((byte) 1)));
            if (CollectionUtils.isNotEmpty(shopGoodsList)){
                /** 遍历商品推荐 **/
                data.put("total", shopGoodsList.size());
                data.put("searchCount", true);
                for (ShopGoods shopGoodsInfo : shopGoodsList){
                    shopGoodsInfo.setHotSalesVolume(0);
                    /** 遍历商品销量 **/
                    for (Map.Entry<String,Integer> hotInfo : list){
                        if (shopGoodsInfo.getId().equals(hotInfo.getKey())){
                            /** 存储商品销量 **/
                            shopGoodsInfo.setHotSalesVolume(hotInfo.getValue());
                            /** 保存商品信息 **/
                            records.add(shopGoodsInfo);
                            break;
                        }
                    }
                }
            }
            /** 保存商品信息 **/
            data.put("records", records);
            int num = page * size;
        }
        return data;
    }

    private IPage<ShopGoods> getGoodsInfosIncludeChildrenByCatId(String catId, Integer pagesize, Integer currentPage) {
        /** 获取分类商品信息--开始 **/
        /** 获取子级分类信息--开始 **/
        ShopCategory categoryTop = categoryMapper.selectById(catId);;
        List<ShopCategory> categoryMiddle = null;
        List<List<ShopCategory>> categoryEnd = new ArrayList<>();
        categoryMiddle = categoryMapper.selectList(new QueryWrapper<>(new ShopCategory().setParentId(categoryTop.getId())));
        if (CollectionUtils.isNotEmpty(categoryMiddle)){
            /** 本分类子级分类不为空 **/
            for (ShopCategory categoryMiddleInfo : categoryMiddle) {
                /** 获取子级的子级信息 **/
                List<ShopCategory> categoryEndInfo = categoryMapper.selectList(new QueryWrapper<>(new ShopCategory().setParentId(categoryMiddleInfo.getId())));
                if (CollectionUtils.isNotEmpty(categoryEndInfo)){
                    /** 子级的子级信息不为空 **/
                    categoryEnd.add(categoryEndInfo);
                }
            }
        }
        /** 获取子级分类信息--结束 **/
        /** 获取所有分类ID--开始 **/
        /** 获取Top分类ID **/
        List<String> goodsIds = new ArrayList<>();
        goodsIds.add(categoryTop.getId());
        /** 获取Middle分类ID **/
        if (CollectionUtils.isNotEmpty(categoryMiddle)){
            for (ShopCategory categoryMiddleInfo : categoryMiddle) {
                goodsIds.add(categoryMiddleInfo.getId());
            }
        }
        /** 获取End分类ID **/
        if (CollectionUtils.isNotEmpty(categoryEnd)){
            for (List<ShopCategory> categoryEndInfos : categoryEnd) {
                for (ShopCategory categoryEndInfo : categoryEndInfos) {
                    goodsIds.add(categoryEndInfo.getId());
                }
            }
        }
        /** 获取所有分类ID--结束 **/
        /** 分页获取符合条件的商品 **/
        IPage<ShopGoods> iPage = new Page<>(currentPage, pagesize);
        Wrapper<ShopGoods> wrapper = new QueryWrapper<>(new ShopGoods().setReviewStatus(Constants.GOODS_STATUS_10)).in("cat_id", goodsIds).orderByAsc("create_date");
        goodsMapper.selectPage(iPage, wrapper);
        /** 获取分类商品信息--结束 **/
        return iPage;
    }

    private List<Object> getGoodsOfHomeUtil(List<ShopGoods> goodsListDB){
        List<Object> data = new ArrayList<>();
        for(ShopGoods goodsDB : goodsListDB){
            /** 装配新品信息 **/
            Map<String, Object> goods = new HashMap<>();
            List<ShopPhoto> photosDB = shopPhotoMapper.selectList(new QueryWrapper<>(new ShopPhoto().setGoodsId(goodsDB.getId()).setType(2)).orderByAsc("photo_sort").last("limit 0,1"));
            goods.put("id", goodsDB.getId());
            goods.put("catId", goodsDB.getCatId());
            goods.put("goodsName", goodsDB.getGoodsName());
            goods.put("imgUrl", photosDB.get(0).getUrl());
            goods.put("goodsBrief", goodsDB.getGoodsBrief());
            goods.put("shopPrice", goodsDB.getShopPrice());
            goods.put("commit", goodsDB.getCommentsNumber());
            goods.put("integral", goodsDB.getIntegral());
            data.add(goods);
        }
        return data;
    }
}
